/*
	The MIT License

	Copyright (c) 2008 IFMO/GameDev Studio

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.
*/
// ui_core.h - 


class EUINode {
	public:
					EUINode			( void );
					~EUINode		( void );
		void		AddChild		( IUIFrame *new_frame );
		void		RemoveChild		( EUINode *node );
		void		RemoveChild		( EUINode *node, EUINode *new_parent );
		void		MoveChildBack	( EUINode *node );
		uint		GetChildNum		( void ) const { return (uint)children.size(); }
		EUINode		*GetChild		( uint n ) { return children[n]; }
		EUINode		*GetParent		( void ) { return parent; }
		IUIFrame	*frame;	
	protected:
		EUINode		*parent;
		vector<EUINode*>	children;
	};


class EUIRootFrame : public IUIFrame {
	public:
							EUIRootFrame		( class EUserInterface *ui );
							~EUIRootFrame		( void );
		virtual void		FMKeyPress			( uint code ) { /*STUB*/ }
		virtual void		FMKeyDown			( uint code ) { /*STUB*/ }
		virtual void		FMPaint				( void );
		virtual void		FMMouseUp			( uint button, float x, float y ) { /*STUB*/ }
		virtual void		FMMouseDown			( uint button, float x, float y ) { /*STUB*/ }
		virtual void		FMMouseClick		( uint button, float x, float y ) { /*STUB*/ }
		virtual void		FMMouseIn			( void ) { /*STUB*/ }
		virtual void		FMMouseOut			( void ) { /*STUB*/ }
		virtual void		FMMouseMove			( uint button, float x, float y ) { /*STUB*/ }
		virtual void		FMProcess			( float delta, float time ) { /*STUB*/ }
		virtual void		FMResize			( float new_width, float new_height );
		virtual void		FMMove				( float new_x, float new_y );
		virtual	void		FMShowFrame			( void ) { /*STUB*/ }
		virtual void		FMHideFrame			( void ) { /*STUB*/ }
		
		//	Frame property stuff :
		virtual IUIFrame	*GetClientArea		( void ) { return this; }
		virtual bool		IsDraggable			( void ) const { return false; }
		virtual bool		IsVisible			( void ) const { return true; }
		virtual bool		IsEnabled			( void ) const { return true; }
		virtual bool		IsSizeable			( void ) const { return false; }
		virtual uiRect_s	GetFrameRect		( void ) const { return rect; }
		virtual uiRect_s	GetClientRect		( void ) const { return rect; }
		virtual float		GetFrameOpacity		( void ) const { return 1.0f; }
		virtual void		GetScrollOffset		( float &dx, float &dy ) { dx=dy=0; }
		virtual const char	*GetFrameText		( void ) const { return "Root"; }
	protected:
		class EUserInterface	*ui;
		uiRect_s	rect;
	};


class EUserInterface : public IUserInterface {
	public:
						EUserInterface	( const ap_t &ap, const gs_t &gs );
						~EUserInterface	( void );
		
		//	UI rendering API :
		virtual void		DrawStringMT		( float x, float y, float size, float tracking, const char *font_raster, const char *string, const EVec4 &color );
		virtual void		DrawStringMTClr		( float x, float y, float size, float tracking, const char *font_raster, const char *string );
		virtual void		DrawStringFont		( float x, float y, const IFont *font, const char *string, const EVec4 &color=EVec4(1,1,1,1) );
		virtual void		DrawTextInRect		( uiRect_s &r, const IFont *font, const char *text, uint align, const EVec4 &color=EVec4(1,1,1,1) );
		virtual float		StringFontLength	( const IFont *font, const char *string );
		virtual void		DrawRect			( float x, float y, float w, float h, const char *image, const EVec4 &color );
		virtual void		DrawBorderRect		( float x, float y, float w, float h, const char *image, const EVec4 &color );
		virtual void		DrawBorderRectTop	( float x, float y, float w, float h, const char *image, const EVec4 &color );
		virtual void		DrawBorderRectBottom( float x, float y, float w, float h, const char *image, const EVec4 &color );
		virtual IFont		*RegisterFont		( const char *path );

		//	UI frame management :
		virtual void		AttachFrame			( IUIFrame *parent, IUIFrame *frame );
		virtual void		DetachFrame			( IUIFrame *frame );
		virtual uint		GetFrameChildNum	( IUIFrame *frame );
		virtual IUIFrame	*GetFrameChild		( IUIFrame *frame, uint n );
		virtual IUIFrame	*GetFrameParent		( IUIFrame *frame );
		
		virtual	void		SetForegroundFrame	( IUIFrame *frame );
		virtual	void		SetActiveFrame		( IUIFrame *frame );
		virtual void		ShowFrame			( IUIFrame *frame );
		virtual void		HideFrame			( IUIFrame *frame );
		virtual uiRect_s	GetDragRect			( void );
		virtual IUIFrame	*GetDraggingFrame	( void );
		virtual	IUIFrame	*GetFrameUnderCursor( void );
		virtual	IUIFrame	*GetActiveFrame		( void );
		virtual	void		RenderFrames		( void );
		virtual	void		ProcessFrames		( void );
		virtual void		GetAbsolutePosition	( IUIFrame *frame, float &x, float &y );

		//	UI feedback stuff :		
		virtual void		KeyPress			( uint code );
		virtual void		KeyDown				( uint code );
		virtual void		MouseMove			( const mouseInput_s *mouse_input );

		//	UI hook stuff :	
		virtual IUIHook		*GetKeyboardHook		( void );
		virtual void		SetKeyboardHook			( IUIHook * hook );

		virtual IUIHook		*GetMouseHook			( void );
		virtual void		SetMouseHook			( IUIHook * hook );

	public:
		ISystem			*sys;
		ICore			*core;
		IConsole		*con;
		IShell			*shell;
		IRenderSystem	*rs;
		IFileSystem		*fs;
		IVar			*ui_debug;
		IUIHook			*keyboard_hook;
		IUIHook			*mouse_hook;
		
	protected:
		void			InitFrameManager		( void );
		void			ShutdownFrameManager	( void );
		void			DrawFrameRecursive		( EUINode *node, EVec4 color );
		void			ProcessFrameRecursive	( EUINode *node );
		void			EmitMouseEvents			( void );
		EUINode			*FindFrameNode			( IUIFrame *frame );
		EUINode			*RecursiveSearch		( EUINode *node, IUIFrame *frame );
		void			BeginDragging			( IUIFrame *frame, float x, float y );
		void			EndDragging				( void );
		
		EUINode			*ui_root;
		mouseInput_s	mouse_input, old_mouse;
		IUIFrame		*mb_down_frame[3];
		IUIFrame		*frame_under_cursor;
		IUIFrame		*active_frame;

		IUIFrame	*drag_frame;
		uiRect_s	drag_start_rect;		
		EVec2		drag_start;
		EVec2		drag_current;
		bool		drag_left, drag_right, drag_top, drag_bottom;
		
	protected:
		vector<EFont*>	font_list;
		void			FreeFonts			( void );
		
	static void ListFonts_f ( EUserInterface *self, int argc, const char **argv);
	};
	
	
	
	
	
	
	
	
	